package com.shemy.fileservice.controller;


import com.shemy.fileservice.config.FileConfig;
import com.shemy.fileservice.domain.FileEntity;
import com.shemy.fileservice.service.FileService;
import com.shemy.fileservice.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;
import java.io.File;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;

/**
 * @Description 文件控制器
 * @Author Dzsom
 * @Date 2018-10-19 23:14
 * @Encoding UTF-8
 * @Version 1.0
 **/
@Api(value = "File",description = "文件上传接口接口",produces = MediaType.ALL_VALUE)
@Controller
@Slf4j
public class FileController {
    private final FileService fileService;

    private final FileConfig fileConfig;

    private final HttpServletRequest request;

    @Autowired
    public FileController(FileService fileService, FileConfig fileConfig, HttpServletRequest request) {
        this.fileService = fileService;
        this.fileConfig = fileConfig;
        this.request = request;
    }

    @GetMapping("/file/{id}")
    @ResponseBody
    public FileEntity getById(@PathVariable("id") String id){
        return fileService.getFileById(id);
    }

    @RequestMapping(value = "/")
    public String index(Model model) {
        model.addAttribute("files", fileService.listFiles());
        return "index";
    }

    /**
     * 单个文件上传
     * @param file 文件
     * @param filePath 路径
     * @return
     */
    @PostMapping("/singleSave")
    @ApiOperation(value = "单个文件上传",httpMethod = "POST")
    @ResponseBody
    @Transactional
    public ResponseEntity<Response> singleSave(MultipartFile file,
                                               @RequestParam(value = "filePath",required = false) String filePath) {
        if (file==null){
            return ResponseEntity.ok().body(new Response(false, "请选择要上传的文件!"));
        }
        //扩展名格式
        String extName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        if (filePath==null) {
            filePath=fileConfig.fileType(extName);
            if (filePath.equals("")) {
                return ResponseEntity.ok().body(new Response(false, "文件格式不支持!"));
            }
        }
        FileEntity fileEntity = myFileUp(filePath, file,null);
        return ResponseEntity.ok().body(new Response(true,"上传成功",fileEntity));

    }

    /**
     * 多个文件上传
     * @param files 文件
     * @param filePath 路径
     * @return
     */
    @PostMapping("/multipleSave")
    @ApiOperation(value = "多个文件上传",httpMethod = "POST")
    @ResponseBody
    @Transactional
    public ResponseEntity<Response> multipleSave(MultipartFile[] files,
                                                 @RequestParam(value = "filePath",required = false) String filePath) {
        if (files==null){
            return ResponseEntity.ok().body(new Response(false, "请选择要上传的文件!"));
        }
        ArrayList<FileEntity> fileEntity=new ArrayList<>();
        for (MultipartFile file :
                files) {
            //扩展名格式
            String extName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
            if (filePath==null) {
                filePath=fileConfig.fileType(extName);
                if (filePath.equals("")) {
                    return ResponseEntity.ok().body(new Response(false, "文件格式不支持!"));
                }
            }
            fileEntity.add(myFileUp(filePath, file,null));
        }

        return ResponseEntity.ok().body(new Response(true,"上传成功",fileEntity));
    }

    /**
     * 删除文件
     * @param filePath
     * @return
     */
    @PostMapping("/dropFile")
    @ApiOperation(value = "删除文件",httpMethod = "POST")
    @Transactional
    public ResponseEntity<Response> dropFile(String id) {
        FileEntity file = fileService.getFileById(id);
        if (file==null){
            return ResponseEntity.ok().body(new Response(false, "文件不存在!"));
        }
        String path = fileConfig.getHardDisk()+File.separator+ file.getPath();
        if(FileUtil.delFile(path)){
            fileService.removeFile(id);
        }else {
            return ResponseEntity.ok().body(new Response(false, "删除失败!"));
        }
        return ResponseEntity.ok().body(new Response(true, "删除成功！"));
    }

    /**
     * 修改文件
     * @param id 文件id
     * @param file 文件
     * @param filePath 路径
     * @return
     */
    @PostMapping("/modifyFile")
    @ResponseBody
    @ApiOperation(value = "修改文件",httpMethod = "POST")
    @Transactional
    public ResponseEntity<Response> handleFileUpload(String id,MultipartFile file,
                                                     @RequestParam(value = "filePath",required = false) String filePath) {
        if(id==null){
            return ResponseEntity.ok().body(new Response(false, "文件id不能为空!"));
        }
        if (file==null){
            return ResponseEntity.ok().body(new Response(false, "请选择要上传的文件!"));
        }
        FileEntity oldFile = fileService.getFileById(id);
        if(oldFile==null){
            return ResponseEntity.ok().body(new Response(false, "文件id不存在!"));
        }
        //扩展名格式
        String extName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        if (filePath==null) {
            filePath=fileConfig.fileType(extName);
            if (filePath.equals("")) {
                return ResponseEntity.ok().body(new Response(false, "文件格式不支持!"));
            }
        }
        FileEntity fileEntity = myFileUp(filePath, file, oldFile.getId());
        return ResponseEntity.ok().body(new Response(true, "修改成功！",fileEntity));
    }

    /**
     * 上传指定类型的文件
     * @param file 文件
     * @param filePath 路径
     * @param type 文件类型(1.Image ,2.Video ,3.Document ,4.Music)
     * @return
     */
    @PostMapping("/typeFile")
    @ResponseBody
    @ApiOperation(value = "上传指定类型的文件",httpMethod = "POST")
    @Transactional
    public ResponseEntity<Response> handleFileType(MultipartFile file,Integer type,
                                                   @RequestParam(value = "filePath",required = false) String filePath){
        //扩展名格式
        String extName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        if(fileConfig.fileByType(extName, type)){
            return this.singleSave(file,filePath);
        }
        return ResponseEntity.ok().body(new Response(true, "文件类型错误！"));
    }

    /**
     * 上传文件到文件夹
     * @param folder 文件夹
     * @param file 上传的文件
     * @param id 文件id(修改文件时需要传)
     * @return
     */
    private FileEntity myFileUp(String folder, MultipartFile file,String id) {
        String fileCode;
        if (id==null){
            fileCode = MD5Util.getUUID();
        }else {
            fileCode=id;
        }
        String returnName= FileUpload.fileUp(file,fileConfig.getHardDisk()+File.separator+folder, fileCode);
        String saveName = folder + File.separator +returnName;
        log.warn("This file has been uploaded: "+saveName);
        FileEntity fileEntity = new FileEntity(fileCode,file.getOriginalFilename(),file.getContentType(),saveName,file.getSize());
        fileEntity.setIpAddress(WebUtil.getIpAddress(request));
        try {
            fileEntity.setMd5( MD5Util.getMD5(file.getInputStream()));
        } catch (NoSuchAlgorithmException | IOException e) {
            e.printStackTrace();
        }
        return fileService.saveFile(fileEntity);
    }

}
